﻿using System;
using System.Collections.Generic;
using Assist;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using YJKRGeometry;

namespace StructureModelDeduction.Data
{
	public abstract class ElementDataPack
	{
		public ElementId SelfElementId
		{
			get
			{
				return this.m_elementId;
			}
		}

		public BoundingBoxXYZ TransFormedBoundBox
		{
			get
			{
				return this.m_boundBox;
			}
			set
			{
				this.m_boundBox = value;
			}
		}

		public Document SelfDoc
		{
			get
			{
				return this.m_doc;
			}
		}

		public string StrTypeName
		{
			get
			{
				return this.strTypeName;
			}
			set
			{
				this.strTypeName = value;
			}
		}

		public CurveArray ArCrvEdage
		{
			get
			{
				return this.m_arCrvEdage;
			}
			set
			{
				this.m_arCrvEdage = value;
			}
		}

		public ElementDataPack(Document Doc, ElementId LinkInstanceId, ElementId elementId, Transform LinkDocTransForm, ExternalCommandData cmdData)
		{
			this.m_doc = Doc;
			this.m_LinkInstanceId = LinkInstanceId;
			this.m_elementId = elementId;
			this.m_LinkDocTransForm = LinkDocTransForm;
			this.m_arCrvEdage = new CurveArray();
			this.m_cmdData = cmdData;
		}

		public void GetBoundingBox()
		{
			Element element = this.m_doc.GetElement(this.m_elementId);
			BoundingBoxXYZ boundingBoxXYZ = element.get_BoundingBox(null);
			if (boundingBoxXYZ != null)
			{
				XYZ xyz = this.m_LinkDocTransForm.OfPoint(boundingBoxXYZ.Min);
				XYZ xyz2 = this.m_LinkDocTransForm.OfPoint(boundingBoxXYZ.Max);
				this.TransFormedBoundBox = new BoundingBoxXYZ();
				double minOrMaxValue = this.GetMinOrMaxValue(xyz.X, xyz2.X, true);
				double minOrMaxValue2 = this.GetMinOrMaxValue(xyz.Y, xyz2.Y, true);
				double minOrMaxValue3 = this.GetMinOrMaxValue(xyz.Z, xyz2.Z, true);
				double minOrMaxValue4 = this.GetMinOrMaxValue(xyz.X, xyz2.X, false);
				double minOrMaxValue5 = this.GetMinOrMaxValue(xyz.Y, xyz2.Y, false);
				double minOrMaxValue6 = this.GetMinOrMaxValue(xyz.Z, xyz2.Z, false);
				this.TransFormedBoundBox.Min = new XYZ(minOrMaxValue, minOrMaxValue2, minOrMaxValue3);
				this.TransFormedBoundBox.Max = new XYZ(minOrMaxValue4, minOrMaxValue5, minOrMaxValue6);
			}
		}

		public double GetMinOrMaxValue(double value1, double value2, bool isMin)
		{
			if (Geometry.LessThan(value1, value2))
			{
				if (isMin)
				{
					return value1;
				}
				return value2;
			}
			else
			{
				if (isMin)
				{
					return value2;
				}
				return value1;
			}
		}

		public bool GetZFaceLoop(out List<Curve> lstCrv)
		{
			lstCrv = new List<Curve>();
			Element element = this.m_doc.GetElement(this.m_elementId);
			GeometryElement ge = element.get_Geometry(new Options
			{
				ComputeReferences = true
			});
			List<GeometryObject> geometryObjectArray = RevitVersionFuncs.GetGeometryObjectArray(ge);
			foreach (GeometryObject geometryObject in geometryObjectArray)
			{
				if (geometryObject is Solid)
				{
					Solid solid = geometryObject as Solid;
					foreach (object obj in solid.Faces)
					{
						Face face = (Face)obj;
						if (face is PlanarFace)
						{
							PlanarFace planarFace = face as PlanarFace;
							XYZ faceFaceNormal = RevitVersionFuncs.GetFaceFaceNormal(planarFace);
							if (faceFaceNormal.IsAlmostEqualTo(-XYZ.BasisZ))
							{
								IList<CurveLoop> edgesAsCurveLoops = planarFace.GetEdgesAsCurveLoops();
								foreach (CurveLoop curveLoop in edgesAsCurveLoops)
								{
									foreach (Curve curve in curveLoop)
									{
										Curve curve2 = curve.CreateTransformed(this.m_LinkDocTransForm);
										lstCrv.Add(curve2);
										this.m_arCrvEdage.Append(curve2);
									}
								}
								return true;
							}
						}
					}
				}
			}
			return false;
		}

		private BoundingBoxXYZ m_boundBox;

		protected Document m_doc;

		protected ElementId m_elementId;

		protected ElementId m_LinkInstanceId;

		private string strTypeName;

		private CurveArray m_arCrvEdage;

		protected Transform m_LinkDocTransForm = Transform.CreateTranslation(new XYZ(0.0, 0.0, 1.0));

		protected ExternalCommandData m_cmdData;
	}
}
